#include "vtor_string.h"

#ifdef __VTOR_STRING__




// 允许不同通道打印输出
int32_t VtorString_ChanPrintString(uint32_t ch, uint8_t* str)
{
	// 把控制字符调整成'?'，便于知道此时输出了控制字符
	VtorString_AdjustControlChar(str);
	return VtorString_ChanPrintBuffer(ch, str, VtorString_Length(str));
}

int32_t VtorString_Print(uint8_t* str)
{
	return VtorString_ChanPrintString(0, str);
}

int32_t VtorString_PrintBuffer(uint8_t* buf, int32_t len)
{
	return VtorString_ChanPrintBuffer(0, buf, len);
}



int32_t VtorString_PrintNumber(int32_t num, int8_t len)
{
	uint8_t strBuf[10] = { 0 };
	uint8_t* str = strBuf;
	int32_t base = 1;
	if (len <= 0)
	{
		return 0;
	}
	if (num < 0)
	{
		*str++ = '-';
		len--;
		num = -num;
	}
	while (len > 0)
	{
		str[--len] = num / base % 10 + '0';
		base *= 10;
	}
	return VtorString_Print(strBuf);
}


uint8_t* VtorString_AppendChar(uint8_t* str, int32_t* len, const uint8_t ch)
{
	if(*len > 2)
	{
		*str++ = ch;
		(*len)--;
		*str = '\0';
	}
	return str;
}


uint8_t* VtorString_AppendFloat(uint8_t* str, int32_t* len, float num)
{
	int d = 6;
	float fractionNum = 0;

	// 整数部分按int方法
	if (num < 0 && *len > 0)
	{
		num = -num;
		*str++ = '-';
		(*len)--;
	}
	VtorString_AppendInt(str, len, (int32_t)num);
	fractionNum = num - (int32_t)num; // 小数
	while (*str && *len > 0)
	{
		str++;
		(*len)--;
	}
	*str++ = '.';
	(*len)--;
	while (d-- && *len > 0)
	{
		fractionNum *= 10;
		*str++ = (int32_t)fractionNum % 10 + '0';
		(*len)--;
	}
	*str = '\0';
	return str;
}

uint8_t* VtorString_AppendInt(uint8_t* str, int32_t* len, int32_t num)
{
	uint8_t* retStr = NULL;
	uint8_t* startStr = NULL;
	if (num < 0 && (*len) > 0)
	{
		*str++ = '-';
		(*len)--;
		num = -num;
	}
	if (0 == num && *len > 0)
	{
		*str++ = '0';
		(*len)--;
		*str = '\0';
		return str;
	}

	startStr = str;
	while (num && *len > 0)
	{
		int singleNum = num  % 10;
		*str++ = singleNum + '0';
		(*len)--;
		num /= 10;
	}
	*str = '\0';
	retStr = str;
	str--;
	while (startStr < str)
	{
		int8_t ch = *str;
		*str = *startStr;
		*startStr = ch;
		startStr++;
		str--;
	}
	return retStr;
}

uint8_t* VtorString_AppendHex(uint8_t* str, int32_t* len, uint32_t num)
{
	uint8_t* retStr = NULL;
	uint8_t* startStr = NULL;
	if (0 == num && *len > 0)
	{
		*str++ = '0';
		(*len)--;
		*str = '\0';
		return str;
	}

	startStr = str;
	while (num && *len > 0)
	{
		int singleNum = num & 0x0f;
		int8_t singleNumChar
			= (singleNum < 10)
			? (singleNum + '0')
			: (singleNum + 'a' - 10);
		*str++ = singleNumChar;
		(*len)--;
		num >>= 4;
	}
	*str = '\0';
	retStr = str;
	str--;
	while (startStr < str)
	{
		int8_t ch = *str;
		*str = *startStr;
		*startStr = ch;
		startStr++;
		str--;
	}
	return retStr;
}

uint8_t* VtorString_AppendMemory(uint8_t* str, int32_t* len, void* mem, int32_t cnt, int8_t width)
{
	int8_t* byteMem = (int8_t*)mem;
	// 对于width未初始化的情况，将其恢复成1
	if(0 == width)
	{
		width = 1;
	}
#ifdef __VTOR_STRING_CONFIG_LITTLE_ENDIAN__
	byteMem += width;
#endif

	while(cnt-- && *len > 2)
	{
		int i;

		for(i = 0; i < width && *len > 2; i++)
		{
#ifdef __VTOR_STRING_CONFIG_LITTLE_ENDIAN__
			uint8_t byteValue = *--byteMem;
#else
			uint8_t byteValue = *byteMem++;
#endif
			*str++ = (byteValue >> 4) < 10
				? ((byteValue >> 4) + '0')
				: ((byteValue >> 4) - 10 + 'a');
			*str++ = (byteValue & 0x0f) < 10
				? ((byteValue & 0x0f) + '0')
				: ((byteValue & 0x0f) - 10 + 'a');
			*len -= 2;
		}
#ifdef __VTOR_STRING_CONFIG_LITTLE_ENDIAN__
		byteMem += (width << 1);
#endif
		*str++ = ' ';
		(*len) --;
	}
	*(str - 1) = '\0';
	return (str - 1);
}


uint8_t* VtorString_AppendString(uint8_t* str, int32_t* len, const uint8_t* str2)
{
	while (*str2 && *len > 0)
	{
		*str++ = *str2++;
		(*len)--;
	}
	*str = '\0';
	return str;
}

int8_t VtorString_CmpString(const uint8_t* str1, const uint8_t* str2)
{
	while (*str1 && *str2)
	{
		if (*str1 > *str2)
			return 1;
		else if (*str1 < *str2)
			return -1;
		str1++;
		str2++;
	}
	return 0;
}

int16_t VtorString_GetSimilarity(const uint8_t* str1, const uint8_t* str2)
{
	int16_t similarity = 0;
	while (*str1 && *str2)
	{
		if (*str1 == *str2)
		{
			similarity++;
		}
		else
		{
			break;
		}
		str1++;
		str2++;
	}
	if(*str2 == '\0')
	{
		// str2到了末尾，大幅度提升相似度
		similarity |= 0x400;
		if(*str1 == '\0')
		{
			// str1到了末尾，更大幅度提升相似度
			similarity |= 0x800;
		}
	}
	return similarity;
}

uint8_t* VtorString_FindFloat(uint8_t* str, float* num)
{
	int32_t signBit = 1;
	int32_t base = 10;
	int32_t wholeNum = 0; // 整数
	float fractionNum = 0.0f; // 小数
	float fractionNumFactor = 1.0f;

	// 找到第一个有效数字0~9,或者+-
	while (*str)
	{
		if ('0' <= *str && *str <= '9')
		{
			break;
		}
		if (*str == '-')
		{
			signBit = -1;
			str++;
			break;
		}
		str++;
	}
	// 找出整数部分（十进制）
	while (1)
	{
		int singleNum = 0;
		if ('0' <= *str && *str <= '9')
		{
			singleNum = *str - '0';
		}
		else
		{
			break;
		}
		wholeNum *= base;
		wholeNum += singleNum;
		str++;
	}
	// 如果有小数点，挑出小数部分
	if ('.' == *str)
	{
		str++;
		while (1)
		{
			int singleNum = 0;
			if ('0' <= *str && *str <= '9')
			{
				singleNum = *str - '0';
			}
			else
			{
				break;
			}
			fractionNumFactor *= base;
			fractionNum *= base;
			fractionNum += singleNum;
			str++;
		}
		fractionNum /= fractionNumFactor;
	}
	*num = wholeNum  + fractionNum;
	*num *= signBit;
	return str;
}

uint8_t* VtorString_FindInt(uint8_t* str, int32_t* num)
{
	int32_t signBit = 1;
	int32_t base = 10;
	*num = 0;
	// 找到第一个有效数字0~9,或者+-
	while(*str)
	{
		if('0' <= *str && *str <= '9')
		{
			break;
		}
		if(*str == '-')
		{
			signBit = -1;
			str++;
			break;
		}
		str++;
	}
	if('0' == *str && ('x' == *(str+1) || 'X' == *(str+1)))
	{
		base = 16;
		str += 2;
	}
	while(1)
	{
		int singleNum = 0;
		if(10 == base)
		{
			if('0' <= *str && *str <= '9')
			{
				singleNum = *str - '0';
			}
			else
			{
				break;
			}
		}
		if(16 == base)
		{
			if('0' <= *str && *str <= '9')
			{
				singleNum = *str - '0';
			}
			else if('a' <= *str && *str <= 'f')
			{
				singleNum = *str - 'a' + 10;
			}
			else if('A' <= *str && *str <= 'F')
			{
				singleNum = *str - 'A' + 10;
			}

			else
			{
				break;
			}
		}
		*num *= base;
		*num += singleNum;
		str++;
	}
	*num *= signBit;
	return str;
}

// 裁断字符串，并返回首地址
uint8_t* VtorString_CutString(uint8_t* str, int32_t* subStrAddr)
{
	uint8_t* adjustStr = NULL;
	if(*str == '"')
	{
		*str = '\0';
		str++;
		*subStrAddr = (int32_t)str; // 记录字符串地址，并返回
	}
	adjustStr = str;
	// \" 代表输入双引号，不再辜负双引号
	// \\ 代表输入捺杠，不辜负捺杠
	while(*str) // 既然是可视字符串，不允许null
	{
		// 捺杠 启动转义，调整str
		if(*str == '\\')
		{
			str++;
			// 支持常见的转义字符
			*str = (*str == 'r') ? '\r' : *str;
			*str = (*str == 'n') ? '\n' : *str;
			*str = (*str == 't') ? '\t' : *str;
		}
		// 如果没启动转义
		// 才针对双引号执行截断操作
		else if(*str == '"')
		{
			*str = '\0';
			*adjustStr = '\0';
			adjustStr++;
			str++;
			break;
		}
		*adjustStr = *str;
		adjustStr++;
		str++;
	}
	
	return str;
}

// 裁断hex字符串，并返回首地址
uint8_t* VtorString_CutHexString(uint8_t* str, int32_t* subStrAddr)
{
	uint8_t* hexMem = NULL; // 以byte方式缓冲进此地址
	int8_t hexIdx = 0; // 每两个hex构成一个char
	uint8_t singleHex = 0; // 记录两个
	if(*str == '\'')
	{
		*str = '\0';
		str++;
		*subStrAddr = (int32_t)str; // 记录字符串地址，并返回
	}
	hexMem = str; // 重新指向hexstr
	while(*str && *str != '\'')
	{
		if('0' <= *str && *str <= '9')
		{
			singleHex |= *str - '0';
			hexIdx++;
		}
		else if('a' <= *str && *str <= 'f')
		{
			singleHex |= *str - 'a' + 10;
			hexIdx++;
		}
		else if('A' <= *str && *str <= 'F')
		{
			singleHex |= *str - 'A' + 10;
			hexIdx++;
		}
		else
		{
			// 忽略其他所有字符
			str++;
			continue;
		}
		
		if(hexIdx & 0x01) // 如果是奇数，说明要调整singleNum
		{
			singleHex <<= 4;
		}
		else
		{
			// 偶数，说明拿到了两个十六进制数，可组成一个char
			// 赋值给hexString，并将singleNum清零
			*hexMem = singleHex;
			hexMem++;
			singleHex = 0;
		}
		
		str++;
	}
	*hexMem = '\0'; // 设置截断符
	// 如果是边界符，置null，并移动到下一位
	// 否则（一般是null），直接返回null
	if(*str == '\'')
	{
		*str = '\0';
		str++;
	}
	return str;
}

uint8_t* VtorString_GetNextValueType(uint8_t* str, int8_t* valType)
{
	// 忽略空格，等待数字或双引号或单引号
	*valType = VtorVar_Void;
	while(*str)
	{
		if('"' == *str)
		{
			*valType = VtorVar_String;
		}
		else if('\'' == *str)
		{
			*valType = VtorVar_HexString;
		}
		else if(':' == *str)
		{
			*valType = VtorVar_Memory;
		}
		else if('0' == *str && ('x' == *(str + 1) || 'X' == *(str + 1)))
		{
			*valType = VtorVar_Hex;
		}
		else if(('0' <= *str && *str <= '9')
			|| ('+' == *str || '-' == *str))
		{
			*valType = VtorVar_Int;
		}
		if(VtorVar_Void != *valType)
		{
			break;
		}
		str++; // 指向下一个数字
	}
	return str;
}

uint8_t* VtorString_FindVariable(uint8_t* str, VtorVar* var)
{
// 先过滤掉字符串中不可用的东西字母，符号，空格，等
	while (*str)
	{
		if ('\'' == *str)
		{
			var->type = VtorVar_Char;
			var->intVar = *(str+1); // 字符串使用值
			str += 2; // 跳过字符和单引号
			break;
		}
		if ('"' == *str)
		{
			int16_t i = 0;
			var->type = VtorVar_String;
			while(*str) // 对var进行内存复制
			{
				if(*str != '"')
				{
					var->strVar[i++] = *str;
					str++;
				}
				var->strVar[i] = '\0'; // 添加结束符
			}
			break;
		}
		if ('0' == *str
			&&('x' == *(str + 1) || ('X' == *(str + 1))))
		{
			var->type = VtorVar_Hex;
			str = VtorString_FindInt(str, &var->intVar);
			break;
		}
		if ('0' <= *str && *str <= '9')
		{
			var->type = VtorVar_Int;
			while(*str)
			{
				if ('.' == *str)
				{
					var->type = VtorVar_Float;
					str = VtorString_FindFloat(str, &var->floatVar);
					break;
				}
				// 整形数据结束了，认为是整形属性
				if (*str < '0' || '9' < *str)
				{
					str = VtorString_FindInt(str, &var->intVar);
					break;
				}
				str++;
			}
			break;
		}
		str++;
	}
	return str;
}


void VtorString_Clear(uint8_t* str)
{
	*str = '\0';
}

int32_t VtorString_Length(const uint8_t* str)
{
	const uint8_t *ptr=str;
	while(*str++!='\0');
	return str-ptr-1;
}

// 预处理，截断注释
uint8_t* VtorString_Preprocess(uint8_t* str)
{
	uint8_t* asciiHeadStr = NULL;
	while(*str)
	{
		if(' ' == *str || '\t' == *str)
		{
		}
		else
		{
			break;
		}
		str++;
	}
	// 跳过空格，跳过tab
	asciiHeadStr = str;
	while(*str)
	{
		if('/' == *str
			&& '/' == *(str+1))
		{
			*str = '\0';
			break;
		}
		str++;
	}
	return asciiHeadStr;
}

void VtorString_AdjustControlChar(uint8_t* str)
{
	while (*str)
	{
		// 如果不在可显示范围内
		if(*str < ' ' || '~' < *str)
		{
			// 如果是常用控制字符，保留控制字符的功能
			if(*str == '\r' || *str == '\n' || *str == '\t' || *str == '\b')
			{
			}
			else
			{
				// 如果不是常用控制字符，将其调整为可显示字符'?'
				*str = '?'; // ? 的ascii 是 0x3f（十进制63）
			}
		}
		str++;
	}
}

uint8_t* VtorString_FindString(uint8_t* str, uint8_t* dstStr)
{
	uint16_t pos;
	while (*str)
	{
		if (*str != *dstStr)
		{
			str++;
			continue;
		}
		for (pos = 0; *(dstStr + pos); pos++)
		{
			if (*(str + pos) != *(dstStr + pos))
			{
				break;
			}
		}
		if ('\0' == *(dstStr + pos))
		{
			break;
		}
		str++;
	}
	return str;
}

#endif // __VTOR_STRING__

